﻿package djw.tween {
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.system.System;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;
	
	/**
	 * TweenDark is an open-source, high performance tweening engine.
	 * 
	 * @author Dale J Williams
	 */
	public class TweenDark {
		
		static public const VERSION		:String		= "0.666.3";
		
		static private var _tweens		:Dictionary	= new Dictionary(false);	// tween references
		static private var _timer		:Sprite 	= new Sprite();
		static private var _instance	:TweenDark;								// there can be only one				
		
		static internal var frames		:int;		// total number of frames occurred since doom instanciated
		static internal var fps			:int;		// current framerate
		static internal var difference	:int;		// small amount of time between current frame and previous
		static internal var time		:int;		// total time since instanciation
		
		static private function loop(e:Event):void {
			frames++; 													
			difference = getTimer() - time; 						
			time += difference;						
			fps = frames / time * 1000;
			for each(var tween:TDTween in _tweens)
				tween.loop(time); 		
		}
		
		/**
		 * TweenDark - enforced by Satan.
		 */
		public function TweenDark(enforcer:Satan) {
			trace("---\n Welcome to TweenDark v" + VERSION + "\n---");
			_timer.addEventListener(Event.ENTER_FRAME, loop); 
		}
		
		/**
		 * Will apply tween to the target
		 * 
		 * @param	target		target object to be tweened
		 * @param	duration	Duration of TDTween in seconds
		 * @param	propertites	Properties of object to be manipulated/applied.
		 * @return	the tween applied.
		 */
		static public function to(target:Object, duration:Number, properties:Object):TDTween { 
			if (!_instance) _instance = new TweenDark(new Satan());
			if (!target) return null;
			var tween:TDTween = _tweens[target] = new TDTween();			
			tween.init(target, duration, properties);
			return tween;
		}
		
		/**
		 * Will stop the altered object from from further tweening.
		 * @param	target 	object being tweened.
		 */
		static public function kill(target:Object):void {
			if (_tweens[target])
				delete _tweens[target];
		}
				
		static public function play(tween:TDTween):void {
			_tweens[tween.target] = tween;
		}
		
		static public function stop(tween:TDTween):void {
			kill(tween.target);
		}
		
		/**
		 * Returns true if the target is being tweened.
		 * @param	target	The target (object) to be identified.
		 */
		static public function isTweening(target:Object):Boolean {
			return _tweens[target] != null;
		}
		
		/**
		 * returns the TDTween by identifying the target
		 * @param	target	The target (object) to be identified.
		 * @return	the TDTween (tween) being applied to the soul.
		 */
		static public function getTween(target:Object):TDTween {
			return _tweens[target] || null;
		}
		
	}	
}
internal class Satan { }			// used for singleton enforcement